package com.service;

import com.controller.response.CompanyAccount;
import com.controller.response.DataResponse;
import com.entity.BuildingInfo;
import com.entity.FinanceAccount;
import com.entity.FinanceLoanInfo;
import com.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;

@Service
public class DataService {
    
    @Autowired
    private BuildingInfoRepository buildingInfoRepository;

    @Autowired
    private BuildingRentalRepository buildingRentalRepository;

    @Autowired
    private FinanceAccountRepository financeAccountRepository;

    @Autowired
    private FinanceLoanInfoRepository financeLoanInfoRepository;

    @Autowired
    private CompanyInfoRepository companyInfoRepository;

    @Autowired
    private EngineerProjectInfoRepository engineerProjectInfoRepository;
    
    public DataResponse getData() {

        DataResponse dataResponse = new DataResponse();
        dataResponse.setTotalCompany(companyInfoRepository.count());
        dataResponse.setTotalProject(engineerProjectInfoRepository.count());
        dataResponse.setTotalLoan(BigDecimal.ZERO);
        dataResponse.setTotalFinance(BigDecimal.ZERO);


        List<FinanceLoanInfo> all = financeLoanInfoRepository.findAll();
        all.forEach(loanInfo -> {
            dataResponse.setTotalLoan(dataResponse.getTotalLoan().add(loanInfo.getLoanAmount()));
        });

        BigDecimal maxLoan = all
                .stream()
                .map(FinanceLoanInfo::getLoanAmount)
                .max(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO);

        dataResponse.setMaxLoan(maxLoan);

        BigDecimal maxRate = all
                .stream()
                .map(FinanceLoanInfo::getRate)
                .max(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO);

        dataResponse.setMaxRate(maxRate);
        List<FinanceAccount> allAccount = financeAccountRepository.findAll();
        allAccount.forEach(account -> {
            dataResponse.setTotalFinance(dataResponse.getTotalFinance().add(account.getBalance()));
        });

        Map<String, CompanyAccount> companyAccountMap = new HashMap<>();
        List<String> loanXNames = new ArrayList<>();
        List<BigDecimal> loanY = new ArrayList<>();
        List<BigDecimal> rateY = new ArrayList<>();
        all.forEach(loanInfo -> {
            loanXNames.add(loanInfo.getCompanyName() + "-" + loanInfo.getBankName());
            loanY.add(loanInfo.getLoanAmount());
            rateY.add(loanInfo.getRate());

            if (companyAccountMap.containsKey(loanInfo.getCompanyName())) {
                CompanyAccount companyAccount = companyAccountMap.get(loanInfo.getCompanyName());
                companyAccount.setTotalLoan(companyAccount.getTotalLoan().add(loanInfo.getLoanAmount()));
            } else {
                CompanyAccount companyAccount = new CompanyAccount();
                companyAccount.setCompanyName(loanInfo.getCompanyName());
                companyAccount.setTotalLoan(loanInfo.getLoanAmount());
                companyAccount.setTotalFiance(BigDecimal.ZERO);
                companyAccountMap.put(loanInfo.getCompanyName(), companyAccount);
            }
        });

        dataResponse.setLoanXNames(loanXNames);
        dataResponse.setLoanY(loanY);
        dataResponse.setRateY(rateY);

        allAccount.forEach(account -> {
            if (companyAccountMap.containsKey(account.getCompanyName())) {
                CompanyAccount companyAccount = companyAccountMap.get(account.getCompanyName());
                companyAccount.setTotalFiance(companyAccount.getTotalFiance().add(account.getBalance()));
            } else {
                CompanyAccount companyAccount = new CompanyAccount();
                companyAccount.setCompanyName(account.getCompanyName());
                companyAccount.setTotalLoan(BigDecimal.ZERO);
                companyAccount.setTotalFiance(account.getBalance());
                companyAccountMap.put(account.getCompanyName(), companyAccount);
            }
        });

        dataResponse.setAccountData(new ArrayList<>(companyAccountMap.values()));

        return dataResponse;
    }
}